'''
Created on Jan 17, 2011

@author: Administrator
'''

import core

ATTR_AUTH = 'shell_auth'

class User(object):
    
    def __init__(self, name):
        self.name = name
        self.sudoer = False

def auth(func):
    setattr(func, ATTR_AUTH, True)
    return func        

def auth_needed(func):
    return getattr(func, ATTR_AUTH, False)

def toggle_service(service, toggle):
    toggle = toggle != 'off'
    if toggle:
        service.start()
    else:
        service.stop()

class BaseShell(object):
    '''
    classdocs
    '''

    BAD_PASS_MSG = u'nieprawidlowy numer imei'


    def __init__(self, password):
        '''
        Constructor
        '''
        self.password = password
    
    def validate_password(self, password):
        if password != self.password:
            raise core.BadAuthCmdException()
    
    def _handle(self, cmd):
        meth = self._resolve_meth(cmd)
        if auth_needed(meth):
            self.validate_auth(cmd.user)
        return self._execute(meth, cmd.user, cmd.params)
        
    def _execute(self, meth, user, params):
        got_auth = self.got_auth(user)
        try:
            r = meth(user, params)
        except core.CmdException, ce:
            ce.got_auth = got_auth
            raise ce
        except Exception, e:
            raise core.CmdInternalException(got_auth=got_auth, internal=e)
        return r
    
    def _resolve_meth(self, cmd):
        meth_name = 'handle_%s' % cmd.name
        got_auth = self.got_auth(cmd.user)
        try:
            meth = self.__getattribute__(meth_name)
        except:
            raise core.BadCmdException(got_auth=got_auth)
        return meth
    
    def interpret(self, cmd):
        return self._handle(cmd)


class SniffyShell(BaseShell):

    def __init__(self, password, env):
        super(SniffyShell, self).__init__(password)
        self.env = env
        self.master = None
        
    def got_auth(self, user):
        is_master = self.master is not None and user.name == self.master.name
        return user.sudoer or is_master

    def validate_auth(self, user):      
        if not self.got_auth(user):
            raise core.BadAuthCmdException()
    
    def handle_server(self, user, params):
        password = params[0]
        self.validate_password(password)
        cmd_els = params[1:]
        name = cmd_els[0]
        params = cmd_els[1:]
        cmd = core.SniffyCmd(user.name, name, params)
        cmd.user.sudoer = True
        self.interpret(cmd)
    
    def handle_own(self, user, params):
        password = params[0]
        self.validate_password(password)
        self.master = user
        
    @auth
    def handle_status(self, user, params):
        svc_name = params[0]
        svc = self.env[svc_name]
        return 'wlaczony' if svc.state else 'wylaczony'  
        
    @auth
    def handle_lello(self, user, params):
        toggle_service(self.env['lello'], params[0])

    @auth
    def handle_remote(self, user, params):
        toggle_service(self.env['remote'], params[0])

